import { readdirSync } from 'fs';
import { sep } from 'path';
import chalk from "chalk";
import { ERROR_PREFIX } from "../cli/ui";
import { ModelApp } from "./model-app";

/**
 * @description 模型应用工厂
 * @export
 * @class ModelAppFactory
 */
export class ModelAppFactory {

    /**
     * @description 实例对象（单例）
     * @protected
     * @static
     * @type {ModelAppFactory}
     * @memberof ModelAppFactory
     */
    protected static instance: ModelAppFactory;

    /**
     * 应用Map
     *
     * @private
     * @type {Map<string, ModelApp>}
     * @memberof ModelAppFactory
     */
    private appMap: Map<string, ModelApp> = new Map();

    /**
     * 激活应用
     *
     * @private
     * @type {ModelApp}
     * @memberof ModelAppFactory
     */
    private activeApp: ModelApp;

    /**
     * @description 应用端口
     * @type {number}
     * @memberof ModelAppFactory
     */
    public port: number = 9527;

    /**
     * @description 获取实例（单例）
     * @static
     * @return {*}  {ModelAppFactory}
     * @memberof ModelAppFactory
     */
    static getInstance(): ModelAppFactory {
        if (!this.instance) {
            this.instance = new ModelAppFactory();
        }
        return this.instance;
    }

    /**
     * 初始化
     *
     * @param {*} options
     * @memberof ModelAppFactory
     */
    public init(options: any) {
        const { type, path, port } = options;
        this.port = port ? port : 9527;
        if (!type || !path) {
            console.error(`\n${ERROR_PREFIX} Start error: ${chalk.red('%s')}`, '请确认预览类型和模型路径是否正确');
            process.exit(1);
        }
        // 读取应用模型目录
        const rootPath = path.slice(0, path.indexOf("PSSYSAPPS")) + "PSSYSAPPS";
        const files = readdirSync(rootPath);
        if (!files || !(files.length > 0)) {
            console.error(`\n${ERROR_PREFIX} Start error: ${chalk.red('%s')}`, '指定模型路径不存在模型数据');
            process.exit(1);
        }

        files.forEach((fileName: string) => {
            const tempOption = JSON.parse(JSON.stringify(options));
            // 启动类型是APP且完整路径以PSSYSAPPS结尾,设置完整路径
            if (tempOption.path && tempOption.path.endsWith("PSSYSAPPS")) {
                tempOption.path = `${tempOption.path}${sep}${fileName}`;
            }
            Object.assign(tempOption, { codeName: fileName });
            const modelApp = new ModelApp(tempOption);
            this.appMap.set(fileName, modelApp);
        })
        // 如果大于一个应用模型目录，则设置激活应用
        if (files.length > 0) {
            this.setActiveApp({ codeName: files[0] });
        }
    }

    /**
     * 获取激活应用
     *
     * @return {*} 
     * @memberof ModelAppFactory
     */
    public getActiveApp() {
        return this.activeApp;
    }

    /**
     * 设置激活应用
     *
     * @param {*} args
     * @memberof ModelAppFactory
     */
    public setActiveApp(args: any) {
        const { codeName, host } = args;
        this.activeApp = this.appMap.get(codeName);
    }

    /**
     * 获取所有应用
     *
     * @return {*} 
     * @memberof ModelAppFactory
     */
    public getAllApp() {
        const allApps = []
        this.appMap.forEach((value: ModelApp, key: String) => {
            allApps.push({ codeName: value.codeName, path: value.staticResource });
        })
        return allApps;
    }

}